home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Utilities Professional 1-1500
/
Utilities Professional 1-1500 (1994)(WPD)[!].iso
/
12511500
/
var1312.dms
/
var1312.adf
/
HP11
/
KBD.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-06-11
|
8KB
|
340 lines
#include "exec/types.h"
#include "hp11/hp11.h"
#include "hp11/kbd.h"
#include "hp11/codes.h"
#include "hp11/io.h"
/* Macros to initialise one field of the keyboard structure to a particular type.
This simpilfies (& clarifies) this initialisation. */
#define CODE(code) {Instruction, (Decoder)(code) }
#define ACT(act) {Action, (Decoder)(act) }
#define PREFIX(adr) {Prefix, (adr) }
#define INVALID() {Invalid, NULL }
/* Often used macros which return their agument signaling that it is an instruction,
action or error */
#define RETINS(val) { *code = (val); return(Instruction); }
#define RETACT(val) { *code = (val); return(Action); }
#define RETERR(key) { *code = (key); return(Invalid); }
/* Keys which can follow GTO (or GSB). A -1 indicates am invalid sequence, otherwise
the value is the offset to add to KGTO to obtain the corresponding instruction.
IGTO_LINE is different and valid only for GTO, it indicates a GTO .nnn action */
static BYTE gto_decode[NUMKEYS] = {
10, 11, 12, 13, 14, -1, 7, 8, 9, -1,
-1, -1, -1, -1, OIND_G, -1, 4, 5, 6, -1,
-1, -1, -1, -1, -1, -1, 1, 2, 3, -1,
-1, -1, -1, -1, -1, -1, 0, IGTO_LINE, -1, -1,
-1, -1
};
/* For STO & RCL, cf above */
static BYTE sto_decode[NUMKEYS] = {
-1, -1, -1, -1, -1, -1, 7, 8, 9, ODIV,
-1, -1, -1, OIND_R, OI, -1, 4, 5, 6, OMUL,
-1, -1, -1, -1, -1, KRANDOM, 1, 2, 3, OSUB,
-1, -1, -1, -1, -1, -1, 0, KPOINT, KSIGMA_PLUS, OPLUS,
-1, -1
};
/* Functions which take a numeric argument only (eg eng) can use the numbers
from gto_decode, considering as invalid what isn't a number between 1 & 10 */
#define nb_decode gto_decode
/* Read 3 digits for GTO .nnn & return the value in line. If something other than
a number is entered, return the keycode of the first incorrect code & FALSE */
static BOOL GetLine(short *line)
{
register int cnt = 0, key;
register int dec;
*line = 0;
do {
key = GetKey(); dec = nb_decode[key]; /* Get numeric value */
if (dec >= 0 && dec <= 9) { /* It is a digit */
cnt++;
*line = *line * 10 + dec;
}
else { /* error */
*line = key;
return(FALSE);
}
} while (cnt < 3);
/* 3 digits reads */
return(TRUE);
}
/* Decoder routine for FIX, SCI, ENG, SF, CF, Set. code returns the
instruction/action/keycode, start is the offset for the instruction being
decoded (eg KFIX), max is the maximum value which can be accepted (eg 1 for SF).
For SCI & ENG, a number beyond their max (7) is treated as if it was the max
value (So if you type 'f SCI 8' you will get 'f SCI 7' */
static enum KeyTypes NBDec(short *code, int start, int max)
{
register int key, dec;
key = GetKey(); dec = nb_decode[key];
if (dec >= 0 && dec <= 9) { /* Is a digit */
if (dec <= max) RETINS(start + dec) /* valid ins */
else if (start == KSCI || start == KENG) RETINS(start + max)
/* Special treatment for SCI & ENG */
}
RETERR(key);
}
/* Decoding for HYP & ArcHYP */
static enum KeyTypes HypDec(short *code, int start)
{
int key;
key = GetKey();
if (key >= 12 /* SIN */ && key <= 14 /* TAN */) RETINS(start + key - 12)
else RETERR(key);
}
/* Decoding for GTO, GSB & LBL */
static enum KeyTypes JMPDec(short *code, int start)
{
register int key, dec;
short val;
key = GetKey(); dec = gto_decode[key];
if (dec >= 0 && dec <= 15) RETINS(start + dec); /* 0 to 9, A to E */
switch (dec) {
case IGTO_LINE: if (start == KGTO) /* GTO .nnn */
if (GetLine(&val)) RETACT(IGTO_LINE + val)
else RETERR(val);
case OIND_G: if (start != KLBL) RETINS(start + OIND_G); /* GTO/GSB I */
}
RETERR(key);
}
/* Decoding for STO & RCL, deals with all possible STO's */
static enum KeyTypes REGDec(short *code, int start)
{
register int dec, key, oldoff, offset = 0;
do {
key = GetKey();
dec = sto_decode[key];
oldoff = offset;
if ((dec >= 0 && dec <= 9) /* 0 to 9 end an instruction */
|| /* I & (i) end an instruction if no . was typed before. This
is visible if the offset (ignoring + - * /) is 10 */
((offset % OPLUS) != 10 && (dec == OI || dec == OIND_R)))
RETINS(start + offset + dec);
switch (dec) { /* Special cases & offsets */
case KRANDOM: if (offset == 0 && start == KSTO) RETINS(KSTO_RANDOM); /* STO Random */
case KSIGMA_PLUS: if (offset == 0 && start == KRCL) RETINS(KRCL_SIGMA); /* Recall stats */
case KPOINT: if ((offset % OPLUS) == 0) offset += 10; /* Only one . allowed */
case OPLUS: case ODIV: case OMUL: case OSUB: /* + - * / only if none yet */
if (offset == 0 && start == KSTO) offset = dec;
}
} while (offset != oldoff);
/* if offset not changed then there was an error (the loop is repeated when
the offset changes) */
RETERR(key);
}
/* Decoding for prefixes */
/* --------------------- */
static enum KeyTypes FIXDec(short *code)
{
return(NBDec(code, KFIX, 9));
}
static enum KeyTypes SCIDec(short *code)
{
return(NBDec(code, KSCI, 7));
}
static enum KeyTypes ENGDec(short *code)
{
return(NBDec(code, KENG, 7));
}
static enum KeyTypes SFDec(short *code)
{
return(NBDec(code, KFLAGS + OSF, 1));
}
static enum KeyTypes SETDec(short *code)
{
return(NBDec(code, KFLAGS + OSET, 1));
}
static enum KeyTypes CFDec(short *code)
{
return(NBDec(code, KFLAGS + OCF, 1));
}
static enum KeyTypes HYPDec(short *code)
{
return(HypDec(code, KHYP));
}
static enum KeyTypes ARCHYPDec(short *code)
{
return(HypDec(code, KARCHYP));
}
static enum KeyTypes LBLDec(short *code)
{
return(JMPDec(code, KLBL));
}
static enum KeyTypes GTODec(short *code)
{
return(JMPDec(code, KGTO));
}
static enum KeyTypes GSBDec(short *code)
{
return(JMPDec(code, KGSB));
}
static enum KeyTypes STODec(short *code)
{
return(REGDec(code, KSTO));
}
static enum KeyTypes RCLDec(short *code)
{
return(REGDec(code, KRCL));
}
/* The main kbd, f & g */
/* ------------------- */
struct Key mainKbd[3 * NUMKEYS] = {
/* First the main keyboard (unshifted). All the keys which can be entered
MUST not be INVALID(), otherwise the program enters an infinite loop */
CODE(KSQRT),
CODE(KEXP),
CODE(KEXP10),
CODE(KEXP_YX),
CODE(KINV),
CODE(KCHS),
CODE(KFIG + 7),
CODE(KFIG + 8),
CODE(KFIG + 9),
CODE(KDIV),
ACT(ISST),
PREFIX(GTODec),
CODE(KTRIG + OSIN),
CODE(KTRIG + OCOS),
CODE(KTRIG + OTAN),
CODE(KEEX),
CODE(KFIG + 4),
CODE(KFIG + 5),
CODE(KFIG + 6),
CODE(KMUL),
CODE(KR_S),
PREFIX(GSBDec),
CODE(KRDN),
CODE(KEXG_XY),
ACT(IBACK),
CODE(KENTER),
CODE(KFIG + 1),
CODE(KFIG + 2),
CODE(KFIG + 3),
CODE(KSUB),
ACT(ION),
INVALID(), /* Never tested : f */
INVALID(), /* Never tested : g */
PREFIX(STODec),
PREFIX(RCLDec),
INVALID(), /* This key does not exist : it is hidden by ENTER */
CODE(KFIG + 0),
CODE(KPOINT),
CODE(KSIGMA_PLUS),
CODE(KPLUS),
ACT(IRESET), /* These 2 are pseudo-keys */
ACT(IDISPLAY),
/* now f codes, which can be INVALID() */
CODE(KGSB + OA),
CODE(KGSB + OB),
CODE(KGSB + OC),
CODE(KGSB + OD),
CODE(KGSB + OE),
CODE(KPI),
PREFIX(FIXDec),
PREFIX(SCIDec),
PREFIX(ENGDec),
CODE(KX_LE_Y),
PREFIX(LBLDec),
PREFIX(HYPDec),
CODE(KEXG_X_IND),
CODE(KRCL + OIND_R),
CODE(KRCL + OI),
CODE(KRECT),
CODE(KEXG_XI),
CODE(KDSE),
CODE(KISG),
CODE(KX_GT_Y),
CODE(KPSE),
CODE(KCLR_SIGMA),
ACT(ICLR_PRGM),
CODE(KCLR_REG),
ACT(ICLR_PREFIX),
CODE(KRANDOM),
CODE(KPERM),
CODE(KHMS),
CODE(KTO_RAD),
CODE(KX_NE_Y),
INVALID(), INVALID(), INVALID(), /* ON, f & g */
CODE(KFRAC),
ACT(IUSER),
INVALID(), /* dosen't exist */
CODE(KFACT),
CODE(KESTIMATE),
CODE(KLR),
CODE(KX_EQ_Y),
INVALID(), INVALID(),
/* finally, g codes */
CODE(KSQR),
CODE(KLN),
CODE(KLOG),
CODE(KPERC),
CODE(KDELTA_PERC),
CODE(KABS),
CODE(KDEG),
CODE(KRAD),
CODE(KGRD),
CODE(KX_LT_0),
ACT(IBST),
PREFIX(ARCHYPDec),
CODE(KARC + OSIN),
CODE(KARC + OCOS),
CODE(KARC + OTAN),
CODE(KPOLAR),
PREFIX(SFDec),
PREFIX(CFDec),
PREFIX(SETDec),
CODE(KX_GT_0),
ACT(IP_R),
CODE(KRTN),
CODE(KRUP),
CODE(KRND),
CODE(KCLX),
CODE(KLSTX),
CODE(KCOMB),
CODE(KHR),
CODE(KTO_DEG),
CODE(KX_NE_0),
INVALID(), INVALID(), INVALID(),
CODE(KINT),
ACT(IMEM),
INVALID(),
CODE(KMEAN),
CODE(KSDEV),
CODE(KSIGMA_SUB),
CODE(KX_EQ_0),
INVALID(), INVALID()
};